// 教师量表评价
import {
  FC,
  useEffect,
  useState,
  ReactElement,
  useRef,
  useCallback,
  Key
} from 'react'
import {
  connect,
  Loading,
  EvaluationStateType,
  Dispatch,
  PointInfoType,
  schoolInfoType,
  history
} from 'umi'
import {
  Tree,
  Breadcrumb,
  Table,
  Button,
  Input,
  message,
  Upload,
  Form,
  Select,
  Radio
} from 'antd'
const { Option } = Select
import { Location } from 'history-with-query'
import {
  findNode,
  getParentKeys,
  treeFindPath,
  getChildKeys,
  excelDownload,
  setStorage,
  getStorage
} from '@/utils'

import type { DataNode, TreeProps } from 'antd/es/tree'
import type { FormInstance } from 'antd'
import styles from './index.less'

interface IProps {
  dispatch: Dispatch
  evaluationModel: EvaluationStateType
  location: Location
}

interface FormValues {
  [name: string]: any
}

const ScaleEvaluationPage: FC<IProps> = ({
  dispatch,
  evaluationModel,
  location
}): ReactElement => {
  const { batchCode, type, questionCode, page } = location.query as {
    batchCode: string
    type: string
    questionCode?: string
    page?: string
  }
  const [breadcrumb, setBreadcrumb] = useState<string[]>([])
  const [selectedKeys, setSelectedKeys] = useState<string[]>([])
  const [pageNum, setPageNum] = useState<number>(1)
  const [pageSize, setPageSize] = useState<number>(10)
  const [total, setTotal] = useState<number>(0)
  const [pointType, setPointType] = useState<string>('')
  const [ruleCode, setRuleCode] = useState<string>('')
  const formRef = useRef<FormInstance>(null)
  const [expandedKeys, setExpandedKeys] = useState<Key[]>([])
  // 指标树所有最底层节点
  const allChildKeys = useRef<string[]>([])

  const { pointInfo, pointDetail, schoolInfo, gradeList, scoreRules } =
    evaluationModel

  /**
   *
   * @param e InputEvent
   * @param key 三级指标code
   * @param schoolCode 学校编号
   * @param scope 打分范围
   */
  const handlePoint = (
    e: React.ChangeEvent<HTMLInputElement>,
    key: string,
    schoolCode: string,
    scope: string
  ) => {
    if (ruleCode == '60') {
      return
    }
    // 必须是大于等于0的数字，可以是小数
    let result = e.target.value.replace(/[^\d{1,}\.\d{1,}|\d{1,}]/g, '')
    if (Number(result) > Number(scope)) {
      message.warning(`该项最高得分为${scope}分`)
      return
    }
    let copyData: schoolInfoType[] = JSON.parse(JSON.stringify(schoolInfo))
    copyData.forEach((item, v) => {
      if (item.code == schoolCode) {
        if (!item.score) {
          item.score = []
        }
        let v = item.score.find((item) => Object.keys(item)[0] == key)
        if (!v) {
          let obj = {}
          obj[key] = result
          item.score = [obj, ...item.score]
        } else {
          item.score.forEach((item) => {
            if (Object.keys(item)[0] == key) {
              item[key] = result
            }
          })
        }
      }
    })
    dispatch({
      type: 'evaluationModel/setState',
      payload: {
        schoolInfo: copyData
      }
    })
  }
  const getPointInfo = (batchCode: string, type: string) => {
    dispatch({
      type: 'evaluationModel/function_getPointInfo',
      payload: {
        batchCode,
        type
      }
    })
  }

  // 获取打分规则
  const getScoringRules = (ruleCode: string) => {
    dispatch({
      type: 'evaluationModel/function_getScoringRules',
      payload: {
        ruleCode
      }
    })
  }

  const handlePageChange = (page: number, pageSize: number) => {
    setPageNum(page)
    setPageSize(pageSize)
  }

  const paginationProps = {
    current: pageNum, //当前页码
    pageSize, // 每页数据条数
    showTotal: () => <span>总共{total}项</span>,
    total, // 总条数
    onChange: (page: number, pageSize: number) =>
      handlePageChange(page, pageSize), //改变页码的函数
    hideOnSinglePage: false,
    showSizeChanger: false
  }

  // 保存分数
  const saveScore = (schoolCode: string): void => {
    let json = schoolInfo.find((item) => item.code == schoolCode)

    if (!json) return
    const unitCode = json.code
    let key: string[] = []
    json.score?.forEach((item) => {
      key = [...key, ...Object.keys(item)]
    })
    let value: string[] = []
    json.score?.forEach((item) => {
      value = [...value, ...Object.values(item)] as string[]
    })

    let demo = key.map((item) => ({
      questionCode: item
    }))
    demo.forEach((item, index) => {
      item['ruleCode'] = value[index]
    })

    if (!demo.length) {
      message.warning('请输入分数')
      return
    }

    // 至少要打一项分
    const check = demo.some((item) => item['ruleCode'])
    if (!check) {
      message.warning('请输入分数')
      return
    }

    dispatch({
      type: 'evaluationModel/function_saveScore',
      payload: {
        batchCode,
        json: JSON.stringify(demo),
        type: pointType,
        id: undefined,
        unitCode
      },
      callback: (response) => {
        if (response.code == 200) {
          message.success('保存成功')
        }
      }
    })
  }

  //   将打分点转换为表格列
  const transferColumns = () => {
    return pointDetail?.map((item) => ({
      title: item.name,
      key: item.code,
      render: (text: string, record: schoolInfoType, index: number) => {
        return pointType == '01' || (pointType == '02' && ruleCode == '60') ? (
          <Input
            placeholder="请输入分数"
            onChange={(e) => handlePoint(e, item.code, record.code, item.point)}
            value={
              record.score?.find((v) => Object.keys(v)[0] === item.code)?.[
                item.code
              ] ?? ''
            }
          />
        ) : (
          <Radio.Group
            value={
              record.score?.find((v) => Object.keys(v)[0] === item.code)?.[
                item.code
              ] ?? ''
            }
          >
            {scoreRules.map((item) => (
              <Radio value={item.code} key={item.code}>
                {item.name}
              </Radio>
            ))}
          </Radio.Group>
        )
      }
    }))
  }
  const temp = transferColumns() ?? []

  const constantColumns: any[] = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      render: (_: string, record: schoolInfoType, index: number) => {
        return (
          <span>
            {((pageNum - 1) * pageSize + (index + 1))
              .toString()
              .padStart(2, '0')}
          </span>
        )
      },
      align: 'center'
    },
    {
      title: '学校名称',
      dataIndex: 'name',
      key: 'name',
      align: 'center'
    }
  ]

  let operateColumns = [
    {
      title: '操作',
      dataIndex: 'operation',
      key: 'operation',
      render: (_: string, record: schoolInfoType, index: number) => {
        return pointType == '01' ? (
          <Button type="primary" onClick={() => saveScore(record.code)}>
            保存
          </Button>
        ) : (
          <span className={styles.ponint} onClick={() => goPoint(record)}>
            前往评分
          </span>
        )
      },
      align: 'center'
    }
  ]
  let columns = [...constantColumns, ...temp]
  if (columns.length > 2) {
    columns = [...columns, ...operateColumns]
  }

  // 设置面包屑和请求学校数据
  const setBreadAndSchool = (key: string) => {
    const data = findNode(pointInfo, (node: PointInfoType) => {
      return node.code === key
    })
    // 如果不是最里层的节点，直接退出
    if (!data || data?.children) return
    setRuleCode(data.ruleCode)
    if (data.ruleCode) {
      getScoringRules(data.ruleCode)
    }
    setStorage('maxPoint', data.point)

    setPointType(data.type)
    setSelectedKeys([key])
    const temp = treeFindPath(pointInfo, (data) => data.code === key)
    setBreadcrumb(temp)
    getSchoolInfo({ batchCode, questionCode: key })
    formRef.current?.resetFields()
    setPageNum(1)
    setPageSize(10)
    if (data.type != '01') {
      dispatch({
        type: 'evaluationModel/function_getPointInfoByParentCode',
        payload: {
          batchCode: batchCode,
          parentCode: key,
          type: data.type
        }
      })
    } else {
      dispatch({
        type: 'evaluationModel/setState',
        payload: {
          pointDetail: [data]
        }
      })
    }
  }

  //    获取学校列表
  interface ParamsType {
    batchCode: string
    questionCode: string
    grade?: string
    unitName?: string
  }
  const getSchoolInfo = (params: ParamsType) => {
    const { batchCode, questionCode, grade, unitName } = params
    dispatch({
      type: 'evaluationModel/function_getSchoolInfo',
      payload: {
        batchCode,
        questionCode,
        grade,
        unitName
      }
    })
  }

  // 自定义上传文件方法
  const handleUpload = useCallback(
    (options) => {
      const { file } = options
      const formData = new FormData()
      formData.append('batchCode', batchCode)
      formData.append('uploadFile', file)
      dispatch({
        type: 'evaluationModel/function_upload',
        payload: {
          formData
        },
        callback: (response) => {
          if (response.code == 200) {
            message.success('量表导入成功')
            setBreadAndSchool(selectedKeys[0])
          } else if (response.code == 603) {
            // 导入失败时调用此接口
            dispatch({
              type: 'evaluationModel/function_downloadErrorExcel',
              payload: {
                batchCode
              },
              callback: (response) => {
                excelDownload(response, '量表导入错误信息.xlsx')
              }
            })
          }
        }
      })
    },
    [selectedKeys]
  )

  // 查看具体打分点
  const onSelect: TreeProps['onSelect'] = (selectedKeys) => {
    if (allChildKeys.current.includes(selectedKeys[0] as string)) {
      setBreadAndSchool(selectedKeys[0] as string)
    }
  }

  // 树字段标准化
  const treeFieldsFormat = (arr: PointInfoType[]): DataNode[] => {
    return arr.map((item) => ({
      title: item.name,
      key: item.code,
      children: item.children ? treeFieldsFormat(item.children) : undefined
    }))
  }

  // 获取评审资源
  const getSchoolResourceInfo = (): void => {
    dispatch({
      type: 'evaluationModel/function_getSchoolResourceInfo',
      payload: {
        batchCode,
        unitCode: getStorage('schoolCode'),
        questionCode: selectedKeys[0]
      },
      callback: (response) => {
        if (JSON.stringify(response.obj) == '{}') {
          message.warning('该用户尚未上传资料，不能进行评分')
          return false
        } else {
          history.replace({
            pathname: '/assignment/mark/check-materials',
            query: {
              batchCode,
              type: pointType,
              questionCode: selectedKeys[0],
              page: pageNum.toString()
            }
          })
        }
      }
    })
  }

  // 前往评分
  const goPoint = (record: any) => {
    const { code, score } = record
    setStorage('schoolCode', code)
    if (score) {
      setStorage('score', JSON.stringify(score))
    }
    setStorage('ruleCode', ruleCode)
    setStorage('breadcrumb', JSON.stringify(breadcrumb))

    getSchoolResourceInfo()
  }

  // 下载模板
  const downloadTemplate = useCallback(() => {
    dispatch({
      type: 'evaluationModel/function_downloadTemplate',
      payload: {
        batchCode
      },
      callback: (response) => {
        message.success('模板下载成功')
        excelDownload(response, '量表导入模板.xlsx')
      }
    })
  }, [])

  const onExpand = (expandedKeys: Key[]) => {
    setExpandedKeys(expandedKeys)
  }

  // 搜索
  const onFinish = (values: FormValues) => {
    const { grade, unitName } = values
    getSchoolInfo({
      batchCode,
      questionCode: selectedKeys[0],
      grade: grade == '' ? undefined : grade,
      unitName
    })
    setPageNum(1)
    setPageSize(10)
  }

  // 表单重置
  const resetForm = () => {
    formRef.current?.resetFields()
    getSchoolInfo({ batchCode, questionCode: selectedKeys[0] })
    setPageNum(1)
    setPageSize(10)
  }

  // 查询学段
  const getGradeInfo = () => {
    dispatch({
      type: 'evaluationModel/function_getGradeInfo',
      payload: {}
    })
  }

  useEffect(() => {
    getPointInfo(batchCode, type)
    getGradeInfo()
  }, [])

  // 默认选中第一条
  useEffect(() => {
    if (pointInfo.length) {
      allChildKeys.current = getChildKeys(pointInfo)
      if (questionCode) {
        setSelectedKeys([questionCode])
        setBreadAndSchool(questionCode)
      } else {
        setSelectedKeys([allChildKeys.current[0]])
        setBreadAndSchool(allChildKeys.current[0])
      }

      if (page) {
        setPageNum(Number(page))
      }

      // 展开tree全部节点
      const expankeys = getParentKeys(pointInfo)
      setExpandedKeys(expankeys)
    }
  }, [pointInfo])

  useEffect(() => {
    setTotal(schoolInfo.length)
  }, [schoolInfo])
  return (
    <>
      <div className={styles['pannel-wrapper']}>
        <div className={styles['main-content']}>
          <div className={styles['left-pannel']}>
            <div className={styles['pannel-title']}>教师量表评价指标</div>
            <div className={styles['pannel-content']}>
              <Tree
                treeData={treeFieldsFormat(pointInfo)}
                onSelect={onSelect}
                selectedKeys={selectedKeys}
                expandedKeys={expandedKeys}
                onExpand={onExpand}
              />
            </div>
          </div>
          <div className={styles['right-pannel']}>
            <div className={styles['pannel-title']}>教师评价打分板</div>
            <div className={styles['pannel-content']}>
              <Form
                layout={'inline'}
                onFinish={onFinish}
                ref={formRef}
                initialValues={{ grade: '' }}
              >
                <Form.Item label="学段" name="grade">
                  <Select
                    placeholder="请选择参与学段"
                    style={{ width: '200px' }}
                  >
                    <Option value="">全部</Option>
                    {gradeList.map((item) => (
                      <Option value={item.dictKey} key={item.dictKey}>
                        {item.dictValue}
                      </Option>
                    ))}
                  </Select>
                </Form.Item>
                <Form.Item label="学校名称" name="unitName">
                  <Input placeholder="请输入学校名称" />
                </Form.Item>

                <Form.Item>
                  <Button type="primary" htmlType="submit">
                    搜索
                  </Button>
                  <Button onClick={resetForm}>重置</Button>
                </Form.Item>
              </Form>
              <div className={styles['breadcrumb']}>
                <Breadcrumb separator=">">
                  {breadcrumb.map((item) => (
                    <Breadcrumb.Item key={item}>{item}</Breadcrumb.Item>
                  ))}
                </Breadcrumb>

                <div className={styles['btn-wrapper']}>
                  <Button onClick={downloadTemplate}>下载模板</Button>
                  <Upload
                    showUploadList={false}
                    accept=".xls,.xlsx"
                    customRequest={(options) => handleUpload(options)}
                  >
                    <Button>导入数据</Button>
                  </Upload>
                </div>
              </div>
              <div className={styles['table-wrapper']}>
                <Table
                  dataSource={schoolInfo}
                  columns={columns}
                  rowKey="code"
                  pagination={paginationProps}
                  bordered
                  rowClassName={(record, index) => {
                    let className = 'light-row'
                    if (index % 2 === 1) className = 'dark-row'
                    return className
                  }}
                />
              </div>
            </div>
          </div>
        </div>

        <p className={styles['copy-right']}>
          Copyright@ 2016 成都乐培生科技有限公司 蜀ICP备15018125号
        </p>
      </div>
    </>
  )
}

const mapStateToProps = ({
  evaluationModel,
  loading
}: {
  evaluationModel: EvaluationStateType
  loading: Loading
}) => {
  return {
    evaluationModel,
    evaluationLoding: loading.models.evaluationModel
  }
}

export default connect(mapStateToProps)(ScaleEvaluationPage)
